package com.mapbased.wfw.handler;

import java.io.*;
import java.util.*;

import org.dom4j.*;
import org.dom4j.io.*;
import com.mapbased.wfw.*;

/**
 * <p>Title: </p>
 *
 * <p>Description: </p>
 *
 * <p>Copyright: Copyright (c) 2006</p>
 *
 * <p>Company: mapbased.com</p>
 *
 * @author chy_hs(Baily)
 * @version 1.0
 */


public class NavBorder
    extends PageHandler
{
    public static class MenuItem
        implements Comparable
    {
        /**
         * url ,if start with "/",will auto add "http://webroot/!sn"
         */
        public String url;
        public String caption;
        public String name;
        public int order;
        public MenuItem[] sub;

        java.util.Map subMap=new java.util.HashMap();

        public void toArray()
        {

            java.util.List l=new java.util.ArrayList();
            l.addAll(this.subMap.values());
            java.util.Collections.sort(l);
            this.sub=new MenuItem[l.size()];
            l.toArray(this.sub);
            this.subMap=null;
        }

//        public void mergeFrom(MenuItem m)
//        {
//            if(this.url == null || this.url.trim().equals(""))
//            {
//                this.url=m.url;
//                //    this.layerId=m.layerId;
//
//            }
//            if(this.order > m.order)
//            {
//                this.order=m.order;
//            }
//            this.subMap.putAll(m.subMap);
//
//        }

        /**
         * Compares this object with the specified object for order.
         *
         * @param o the Object to be compared.
         * @return a negative integer, zero, or a positive integer as this
         *   object is less than, equal to, or greater than the specified
         *   object.
         * @todo Implement this java.lang.Comparable method
         */
        public int compareTo(Object o)
        {
            MenuItem m=(MenuItem)o;
            return -m.order + this.order;
        }

    }

    String locale;

  //  GlobalRef global;
    String webroot;
    MenuItem[] menuItems;
    String configfile="/border/meta/border-config.xml";



    /**
     *
     * @param context RenderContext
     * @return Object:String value to the page to redirect, if is null,this
     *   page
     * @todo Implement this com.mapbased.wfw.PageHandler method
     */
    public Object defaultAction(RenderContext ctx)
    {

        this.generateMenu(this.menuItems,ctx);

        return null;

    }

    private void generateMenu(MenuItem[] mm,RenderContext rc)
    {
        String main=rc.getSureSingleParam("main");
        StringBuffer sb=new StringBuffer(mm.length * 40);
        //   <a class="navbar_@page{servletContext.servletContextName.endsWith(main)}" href="@config{mainroot}/index.html">首页</a>
        MenuItem selected=null;
        for(int i=0;i < mm.length;i++)
        {
            MenuItem m=mm[i];
            if(m.name.equals(main))
            {
                selected=m;
                sb.append(" <a class=\"navbar_true\"  >").append(m.caption).
                    append(
                        "</a>");
            }
            else
            {
                String u=m.url;
                sb.append(" <a class=\"navbar_false\" href=\"");
                if(u.startsWith("/"))
                {
                    sb.append(this.webroot)
                        .append("/!").append(rc.getSureSingleParam("sn")).
                        append(u);

                }
                else
                {
                    sb.append(u);
                }
                sb.append("\" >").append(m.caption).append(
                    "</a>");

            }

        }
        rc.putParam("main",sb.toString());

        if(selected != null)
        {
            String sub=rc.getSureSingleParam("sub");
            sb.setLength(0);
            mm=selected.sub;
            for(int i=0;i < mm.length;i++)
            {
                MenuItem m=mm[i];
                if(m.name.equals(sub))
                {
                    sb.append(" <a class=\"subbar_true\"  >").append(m.caption).
                        append("</a>");
                }
                else
                {
                    sb.append(" <a class=\"subbar_false\" href=\"");
                    String u=m.url;
                    if(u.startsWith("/"))
                    {
                        sb.append(this.webroot)
                            .append("/!").append(rc.getSureSingleParam("sn")).
                            append(u);

                    }
                    else
                    {
                        sb.append(u);
                    }
                    sb.append("\" >").append(m.caption).append(
                        "</a>");

                }

            }
            rc.putParam("sub",sb.toString());

        }

    }

    private MenuItem parseMain(Element main)
    {
        MenuItem m=new MenuItem();
        m.order=Integer.parseInt(main.attributeValue("order","10000"));
        m.caption=main.attributeValue("caption","");
        m.name=main.attributeValue("name","");
        m.url=main.attributeValue("url","");

        List sub=main.elements("sub");
        for(int i=0;i < sub.size();i++)
        {
            MenuItem s=this.parseMain((Element)sub.get(i));
            m.subMap.put(s.name,s);
        }

        return m;
    }

    private void parse(java.net.URL u,java.util.Map result)
        throws DocumentException
    {
        SAXReader reader=new SAXReader();

        Document doc=reader.read(u);
        Element root=doc.getRootElement();
        Element nav=root.element("nav");
        if(nav != null)
        {
            List mains=nav.elements("main");
            for(int i=0;i < mains.size();i++)
            {
                Element main=(Element)mains.get(i);
                MenuItem mm=this.parseMain(main);

                MenuItem old=(MenuItem)result.get(mm.name);
                if(old == null)
                {
                    result.put(mm.name,mm);
                }


            }
        }

    }

    private MenuItem[] buildMenuItems(GlobalRef g)
        throws Exception
    {
        //    java.util.List sfobags=new java.util.ArrayList();

        java.util.Map main=new java.util.HashMap();

        java.net.URL url=g.getPageLoader().localeResUrl(
            this.configfile,this.locale);

        this.parse(url,main);

        java.util.List l=new java.util.ArrayList();
        l.addAll(main.values());
        java.util.Collections.sort(l);
        MenuItem[] mm=new MenuItem[l.size()];
        l.toArray(mm);
        for(int i=0;i < mm.length;i++)
        {
            mm[i].toArray();
        }
        for(int i=0;i < mm.length;i++)
        {
            MenuItem m=mm[i];
            if(String.valueOf(m.url).length() < 4)
            {
                if(m.sub.length > 0)
                {
                    m.url=m.sub[0].url;

                }
            }
        }

        return mm;

    }

    /**
     * init
     *
     * @param global GlobalRef
     * @todo Implement this com.mapbased.wfw.PageHandler method
     */
    protected void init(GlobalRef g)
    {
        try
        {
           this.menuItems=this.buildMenuItems(g);

            this.webroot=g.getWfwConfig().getValue("webroot");

        }
        catch(Exception e)
        {

            throw new java.lang.RuntimeException(e);
        }

    }

    /**
     * setLocale
     *
     * @param locale String
     * @throws IOException
     * @todo Implement this com.mapbased.wfw.PageHandler method
     */
    protected void setLocale(String locale)
        throws IOException
    {
        this.locale=locale;
        super.setLocale(locale);

    }

    /**
     *
     * @param ele Element
     * @todo Implement this com.mapbased.wfw.PageHandler method
     */
    protected void fetchAttributs(Element ele)
    {
       this.configfile= ele.attributeValue("config",this.configfile);
    }

}
